package com.qili.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.qili.core.utils.DictTypes;
import com.qili.core.utils.DictUtil;
import com.qili.entity.affaircase.dto.AffairCaseDTO;
import com.qili.entity.base.BaseDict;
import com.qili.entity.search.FileComment;
import com.qili.entity.search.FileReply;
import com.qili.entity.search.GiveUp;
import com.qili.entity.search.dto.FileCommentDTO;
import com.qili.entity.supervisor.FileParse;
import com.qili.entity.supervisor.SupervisorFile;
import com.qili.entity.supervisor.SupervisorFileTemp;
import com.qili.entity.supervisor.dto.SupervisorFileDTO;
import com.qili.entity.supplier.SupplierProject;
import com.qili.entity.supplier.SupplierProjectAccept;
import com.qili.entity.supplier.dto.SupplierProjectDTO;
import com.qili.service.SysUserService;
import com.qili.service.ela.ElasticSerachService;
import com.qili.service.search.FileCommentService;
import com.qili.service.search.FileReplyService;
import com.qili.service.search.GiveUpService;
import com.qili.service.supervisor.SupervisorFileService;
import com.qili.util.*;
import lombok.extern.java.Log;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.search.TotalHits;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author zhaoyongke
 * @date 2021/5/19
 * @description
 */
@Log
@RequestMapping("/search/znSerch")
@Controller
public class ZnSerchController {

    @Autowired
    SupervisorFileService supervisorFileService;
    @Autowired
    GiveUpService giveUpService;
    @Autowired
    FileCommentService fileCommentService;
    @Autowired
    FileReplyService fileReplyService;
    @Autowired
    UploadUtil uploadUtil;
    @Autowired
    private SysUserService userService;

//    @Autowired
//    private SolrTemplate solrTemplate;

    @Autowired
    RestHighLevelClient restHighLevelClient;

    @Autowired
    ElasticSerachService elasticSerachService;

//    @Autowired
//    private SolrClient solrClient;
//    @Autowired
//    RestHighLevelClient highLevelClient;

    /**
     * @param model
     * @Author:zhaoyongke
     * @Description: 智能检索首页
     * @Date:14:26 2021/5/19
     */
    @GetMapping("searchIndex")
    @RequiresPermissions("zn:search")
    public String searchIndex(Model model) {
        List<BaseDict> hostlist = DictUtil.getDictByType(DictTypes.HOTDAY001);
        if (hostlist.size() > 0) {
            // 热门量
            String badtLevel1 = hostlist.get(0).getBadtLevel1();
            model.addAttribute("hotdaydic", badtLevel1);
        }
        List<BaseDict> newlist = DictUtil.getDictByType(DictTypes.NEWDAY001);
        if (newlist.size() > 0) {
            // 文件上传界定 是否是新文件
            String badtLevel1 = newlist.get(0).getBadtLevel1();
            model.addAttribute("newdaydic", badtLevel1);
        }
        return "/retrieval/searchIndex";
    }


    /**
     * @param dto
     * @param request
     * @Author:zhaoyongke
     * @Description: 查询语义关联
     * @Date:13:50 2021/5/24
     */
    @GetMapping(value = "querykeywordYi")
    @ResponseBody
    public JsonUtil querykeywordYi(SupervisorFileDTO dto, HttpServletRequest request) {
        JsonUtil re = new JsonUtil();
        String searchKey = dto.getSearchKey();
        if (StringUtil.isNotBlank(searchKey)) {
            List<BaseDict> projectTypeList = DictUtil.getDictByType(DictTypes.KEYYY);
            for (int i = 0; i < projectTypeList.size(); i++) {
                BaseDict baseDict = projectTypeList.get(i);
                String badtName = baseDict.getBadtName();
                if (badtName.equals(searchKey)) {
                    String badtLevel1 = baseDict.getBadtLevel1();
                    re.setData(badtLevel1);
                    break;
                }
            }
        }
        re.setFlag(true);
        return re;
    }


    /**
     * @param model
     * @param dto
     * @Author:zhaoyongke
     * @Description: 查询详情
     * @Date:18:04 2021/5/20
     */
    @GetMapping("viewDetail")
    public String viewDetail(Model model, SupervisorFileDTO dto) {
        String id = dto.getId();
        System.out.println(id);
        List<SupervisorFileDTO> supervisorFileDTOS = supervisorFileService.selectFileSerch(dto);
        SupervisorFileDTO supervisorFileDTO = supervisorFileDTOS.get(0);
        String fileurl = supervisorFileDTO.getUrl();
        if (StringUtil.isNotBlank(fileurl)) {
            supervisorFileDTO.setUrl(fileurl.substring(uploadUtil.getUploadPath().length() - 1));
        }
        // 文件夹Id
        String superiorId = supervisorFileService.selectByPrimaryKey(id).getSuperiorId();
        SupervisorFile supervisorFilePa = supervisorFileService.selectByPrimaryKey(superiorId);
        String downloadUser = supervisorFilePa.getDownloadUser();
        // 获取当前用户的角色
        List<String> userRoleList = CommonUtil.getUserRoleList();
        Boolean hasDown = false;
        for (int i = 0; i < userRoleList.size(); i++) {
            String roleName = userRoleList.get(i);
            if (StringUtil.isNotBlank(downloadUser)) {
                if (downloadUser.indexOf(roleName) > 0) {
                    hasDown = true;
                    break;
                }


            }


        }


        // downloadUser
        model.addAttribute("file", supervisorFileDTO);
        model.addAttribute("commsize", 0);
        if (hasDown) {
            model.addAttribute("down", 1);
        } else {
            model.addAttribute("down", 0);
        }
        GiveUp up = new GiveUp();
        up.setFileId(dto.getId());
        int i = giveUpService.selectCount(up);
        up.setCreateBy(CommonUtil.getUserId());
        int x = giveUpService.selectCount(up);
        model.addAttribute("dznum", i);
        model.addAttribute("zjdz", x);
        //查询评论
        dto.setFileId(id);
        List<SupervisorFileDTO> commlist = supervisorFileService.selectFileComment(dto);
        if (CollectionUtils.isNotEmpty(commlist)) {
            SupervisorFileDTO cdto = commlist.get(0);
            if (cdto != null) {
                model.addAttribute("commsize", commlist.size());
                model.addAttribute("commlist", commlist);
            }
        }
        // 查询该文件的评论---回复
        List<SupervisorFileDTO> commlistReply = supervisorFileService.selectFileReply(dto);

        model.addAttribute("commlistReply", commlistReply);
        String type = dto.getType();
        String url = "";
        if ("文档".equals(type) || "pdf".equals(type)) {
            url = "/retrieval/viewDetail";
        } else if ("图片".equals(type) || "视频".equals(type)) {
            url = "/retrieval/viewDetailPic";
        } else {
            url = "/retrieval/viewDetail";
        }
        model.addAttribute("filetype", type);
        return url;
    }

    /**
     * @param model
     * @param dto
     * @Author:zhaoyongke
     * @Description: 评论详情
     * @Date:16:43 2021/5/21
     */
    @GetMapping("plAddDetail")
    public String plDeplAddDetailtail(Model model, SupervisorFileDTO dto) {

        model.addAttribute("dto", dto);
        return "/retrieval/plAddDetail";
    }

    @GetMapping(value = "queryFileList")
    @ResponseBody
    public JsonUtil queryFileList(SupervisorFileDTO dto, HttpServletRequest request,String start, String size) {
        JsonUtil reJs = new JsonUtil();
        try { //查询类型
            String type = request.getParameter("type") + "";
            String orderFile = "";
            if ("1".equals(type)) {// 最热
                orderFile = "hotnum";
            } else if ("2".equals(type)) {// 最新
                orderFile = "createDate";
            } else if ("3".equals(type)) {// 点赞数量
                orderFile = "dznum";
            } else {
                // 综合排序  按照权重
                orderFile = "";
            }
            String searchKey = dto.getSearchKey();
            String[] searchKeys = null;
            List<String> queryListstr = new ArrayList<>();
            if (StringUtil.isNotBlank(searchKey)) {
                searchKeys = searchKey.trim().split(" ");
                if (searchKeys != null && searchKeys.length > 0) {
                    for (int i = 0; i < searchKeys.length; i++) {
                        queryListstr.add(searchKeys[i]);
                    }
                }
            }

            List<SupervisorFileDTO> ListRetu = new ArrayList<>();
            SearchResponse searchResponse = null;
            TotalHits totalHits = null;
            Long  totalsize=0L;
            try {
                BoolQueryBuilder boolBuildersearchsql = QueryBuilders.boolQuery();
                List<String> userRoleList = CommonUtil.getUserRoleList();
//                List<String> userRoleList = new ArrayList<>();
//                userRoleList.add("zskuser");
                // 角色过滤
                BoolQueryBuilder rolesql = elasticSerachService.orMatchUnionWithList("examineUser", userRoleList);
                //
                //文件名称
                BoolQueryBuilder fileNamesql = elasticSerachService.orMatchUnionWithList("fileName", queryListstr);
                //搜索关键字
                BoolQueryBuilder searchKeysql = elasticSerachService.orMatchUnionWithList("searchKey", queryListstr);
                // 内容
                BoolQueryBuilder contentsql = elasticSerachService.orMatchUnionWithList("content", queryListstr);


                if (StringUtils.isNotBlank(dto.getBeginDate())) {
                    dto.setBeginDate(dto.getBeginDate().replaceAll("-", ""));
                }
                if (StringUtils.isNotBlank(dto.getEndDate())) {
                    dto.setEndDate(dto.getEndDate().replaceAll("-", ""));
                }
                // 按照时间范围 查询
                RangeQueryBuilder rangeDateBuilder = elasticSerachService.rangeMathQuery("createDate", dto.getBeginDate(), dto.getEndDate());
                //用来表示查询条件的or 关系
                // 提升fileNamesql的 权重为 3 searchkey的权重为2 conent 的权重为 1
                BoolQueryBuilder ChidrenBoolQueryBuilderOr = new BoolQueryBuilder().should(StringUtil.isBlank(orderFile)?fileNamesql.boost(3):fileNamesql).should( StringUtil.isBlank(orderFile)?searchKeysql.boost(2):searchKeysql).should( StringUtil.isBlank(orderFile)?contentsql.boost(1):contentsql);

                BoolQueryBuilder ChidrenBoolQueryBuilder = new BoolQueryBuilder().must(rolesql).must(rangeDateBuilder).must(ChidrenBoolQueryBuilderOr);

                boolBuildersearchsql.must(ChidrenBoolQueryBuilder);
                log.info("开始执行=================================");
                // 分页查询表
                searchResponse = elasticSerachService.searchMessage(boolBuildersearchsql, orderFile,start,size);
                log.info("分页执行成功===================================================");
                //查询出总数

                log.info("执行成功===================================================");
                SearchHit[] hits = searchResponse.getHits().getHits();
                totalsize= searchResponse.getHits().getTotalHits().value;
                log.info(hits.length+"");
                log.info(totalsize+"总条数================================");


                for (int i = 0; i < hits.length; i++) {
                    Map<String, Object> sourceAsMap = hits[i].getSourceAsMap();
                    SupervisorFileDTO supervisorFile = JSON.parseObject(JSON.toJSONString(sourceAsMap), SupervisorFileDTO.class);
                    // 判断是否包含当前用户 ，如果包含就是已经点赞
                    if (StringUtils.isNotBlank(supervisorFile.getGiveUser())) {
                        if (supervisorFile.getGiveUser().indexOf(CommonUtil.getUserId()) >= 0) {
                            supervisorFile.setIsDz("1");
                        }
                    } else {
                        supervisorFile.setIsDz("0");
                    }
                    ListRetu.add(supervisorFile);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
            reJs.setMsg(totalsize+"");
            reJs.setFlag(true);
            reJs.setData(ListRetu);
            log.info("获取成功===================返回数据===================================================================");
//            dto.setUserId(CommonUtil.getUserId());
//            if(StringUtil.isNotBlank(searchKey)){
//                searchKeys = searchKey.trim().split(" ");
//                if(searchKeys!=null && searchKeys.length>0){
//                    dto.setSearchKeys(searchKeys);
//                    dto.setSearchKey(null);
//                }
//            }
//            dto.setSearchKey("");
//            dto.setExamine(CommonUtil.getUserRoleList());
//            List<SupervisorFileDTO> ListRe = supervisorFileService.selectFileSerch(dto);
            return reJs;
        } catch (Exception e) {
            e.printStackTrace();
            reJs.setMsg("获取失败！！" + e.getMessage());
            reJs.setFlag(false);
            return reJs;
        }
    }

    /**
     * @param dto
     * @Author:zhaoyongke
     * @Description: 点赞操作
     * @Date:14:36 2021/5/20
     */
    @RequestMapping("/updateDz")
    @ResponseBody
    public JsonUtil updateDz(SupervisorFileDTO dto) {

        try {
            JsonUtil re = new JsonUtil();
            JSONObject object = new JSONObject();
            GiveUp up = new GiveUp();
            up.setFileId(dto.getId());
            up.setCreateBy(CommonUtil.getUserId());
            int i = giveUpService.selectCount(up);
            Boolean  dzstatus=true;
            if (i == 0) {
                up.setCreateDate(DateUtil.getCurrentDateString());
                giveUpService.insert(up);
                object.put("flag", '1');
            } else {
                giveUpService.delete(up);
                object.put("flag", '0');
                dzstatus=false;
            }
            GiveUp up1 = new GiveUp();
            up1.setFileId(dto.getId());
            int count = giveUpService.selectCount(up1);
            object.put("num", count);
            // 更新es 中的 点赞数量和 点赞人
            SupervisorFile supervisorFile = supervisorFileService.selectByPrimaryKey(dto.getId());
            saveOrUpdateElacSearchData(dto.getId(), "",dzstatus);
            re.setData(object);
            re.setFlag(true);
            re.setMsg("操作成功");
            return re;
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return JsonUtil.error("操作失败:" + e.getMessage());
        }


    }

    /**
     * @param content
     * @Author:zhaoyongke
     * @Description:
     * @Date:19:39 2021/10/7
     */
    public void saveOrUpdateElacSearchData(String fileId, String content,Boolean  dzstatus) {

        try {
            BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
            QueryBuilder queryBuilder = elasticSerachService.queryId(fileId);
            boolBuilder.must(queryBuilder);
            SearchResponse searchResponse = elasticSerachService.searchMessage(boolBuilder, "","","");
            TotalHits totalHits = searchResponse.getHits().getTotalHits();


            Long total = totalHits.value;
            if (total > 0) {
                SearchHit[] hits = searchResponse.getHits().getHits();
                    Map<String, Object> sourceAsMap = hits[0].getSourceAsMap();
                    SupervisorFileDTO file = JSON.parseObject(JSON.toJSONString(sourceAsMap), SupervisorFileDTO.class);
                    log.info("同步es执行结束=======================");

                    //更新操作
                    UpdateRequest updateRequest = new UpdateRequest("swordaa", file.getId());
                    Map<String, Object> jsonMap = new HashMap<>();
//                jsonMap.put("content",content);
                    jsonMap.put("fileName", file.getFileName());
                    jsonMap.put("searchKey", file.getSearchKey());
                    jsonMap.put("id", file.getId());
                    if(dzstatus){
                        // 点赞人
                        jsonMap.put("giveUser", file.getGiveUser()+","+CommonUtil.getUserId());
                    }else{
                        jsonMap.put("giveUser", file.getGiveUser()+"".replace(CommonUtil.getUserId(),""));
                    }
                    // 点赞数量
                    jsonMap.put("dznum", file.getDznum());
                    jsonMap.put("type", file.getType());
                    jsonMap.put("createBy", file.getCreateBy());
                    jsonMap.put("createUsername", file.getCreateUsername());
                    jsonMap.put("url", file.getUrl());
                    jsonMap.put("projectId", file.getProjectId());
                    jsonMap.put("days", file.getDays());
                    jsonMap.put("hotnum", file.getHotnum());
                    jsonMap.put("remark", file.getRemark());
                    jsonMap.put("createDate", file.getCreateDate());
                    // 查询角色
                    jsonMap.put("examineUser", file.getExamineUser());
                    updateRequest.doc(jsonMap);
                UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);

                    System.out.println(update.status());
                }
            } catch(IOException e){
                e.printStackTrace();
            }


        }
        /**
         * @param dto
         * @Author:zhaoyongke
         * @Description: 保存评论
         * @Date:18:06 2021/5/21
         */
        @RequestMapping("/savePL")
        @ResponseBody
        public JsonUtil savePL (SupervisorFileDTO dto){
            try {
                JsonUtil re = new JsonUtil();
                FileComment comment = new FileComment();
                comment.setFileId(dto.getId());
                comment.setCreateBy(CommonUtil.getUserId());
                comment.setCreateDate(DateUtil.getCurrentDateString());
                comment.setContent(dto.getContent());
                fileCommentService.insert(comment);
                SupervisorFileDTO comdto = new SupervisorFileDTO();
                String commentId = comment.getCommentId();
                comdto.setCommentId(commentId);
                comdto.setFileId(dto.getId());
                List<SupervisorFileDTO> comfileList = supervisorFileService.selectFileComment(comdto);
                if (CollectionUtils.isNotEmpty(comfileList)) {
                    SupervisorFileDTO supervisorFileDTO = comfileList.get(0);
                    re.setData(supervisorFileDTO);
                }
                re.setFlag(true);
                re.setMsg("操作成功");
                return re;
            } catch (Exception e) {
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return JsonUtil.error("操作失败:" + e.getMessage());
            }
        }


        /**
         * @param dto
         * @Author:zhaoyongke
         * @Description: 保存评论 回复
         * @Date:18:06 2021/5/21
         */
        @RequestMapping("/savePLHf")
        @ResponseBody
        public JsonUtil savePLHf (SupervisorFileDTO dto){
            try {
                JsonUtil re = new JsonUtil();
                FileReply reply = new FileReply();
                reply.setFileId(dto.getId());
                reply.setCommentId(dto.getCommentId());
                reply.setCreateBy(CommonUtil.getUserId());
                reply.setCreateDate(DateUtil.getCurrentDateString());
                reply.setContent(dto.getContent());
                fileReplyService.insert(reply);
                re.setFlag(true);
                re.setMsg("操作成功");
                return re;
            } catch (Exception e) {
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return JsonUtil.error("操作失败:" + e.getMessage());
            }
        }


    }
